import hashlib
import random

import time

import re
import redis
from datetime import datetime
from flask import Flask, request, make_response
import xml.etree.ElementTree as ET
import uuid

from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import and_, not_

from get_token import REDIS_POOL
from reply_txt import bot_reply
from reply_image import cvt, get_media_id

import pymysql

pymysql.install_as_MySQLdb()

app = Flask(__name__)
# 配置数据库
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@114.116.123.190/Pub?charset=utf8mb4'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)


class Msg(db.Model):
    __tablename__ = 'messages'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    fromUser = db.Column(db.String(64))
    creatTime = db.Column(db.DateTime, default=datetime.now)
    msg = db.Column(db.Text, default='')
    reply_list = db.Column(db.Text, default='')
    reply_user = db.Column(db.Text, default='')
    reply_num = db.Column(db.SmallInteger, default=0)
    is_delete = db.Column(db.Boolean, default=0)

    def __repr__(self):
        return 'Message: %s' % (self.msg)


@app.route('/wx', methods=["GET", "POST"])
def getinput():
    if request.method == "GET":
        # 第一次接入微信服务器的验证
        signature = request.args.get('signature')
        timestamp = request.args.get('timestamp')
        echostr = request.args.get('echostr')
        nonce = request.args.get('nonce')
        token = 'jarvis'
        if len(request.args) == 0:
            return "hello, this is handle view"
        list = [token, timestamp, nonce]
        list.sort()
        s = list[0] + list[1] + list[2]
        hashcode = hashlib.sha1(s.encode('utf-8')).hexdigest()
        if hashcode == signature:
            return echostr
        else:
            print('验证失败')
            return ""

    if request.method == "POST":
        xml_data = ET.fromstring(request.data)
        toUser = xml_data.find('ToUserName').text
        fromUser = xml_data.find('FromUserName').text
        msgType = xml_data.find('MsgType').text

        # 不同内容

        # msgId = xml_data.find('MsgId').text


        # 关注
        if msgType == 'event' and xml_data.find('Event').text == 'subscribe':
            reply = '''<xml>
                    <ToUserName><![CDATA[%s]]></ToUserName>
                    <FromUserName><![CDATA[%s]]></FromUserName>
                    <CreateTime>%s</CreateTime>
                    <MsgType><![CDATA[text]]></MsgType>
                    <Content><![CDATA[%s]]></Content>
                    </xml>'''
            welcome = '欢迎关注Jarvis，您可以回复\n文本消息与机器人聊天(学习型)\n图片消息实现转手绘(像素糙)'
            response = make_response(reply % (fromUser, toUser, str(int(time.time())), welcome))
            response.headers['content-type'] = 'application/xml'
            return response

        # 文本消息
        if msgType == 'text':
            content = xml_data.find('Content').text
            # print(content)
            content_list = re.split('[+＋]', content, 1)
            print(content_list)
            reply = '''<xml>
                    <ToUserName><![CDATA[%s]]></ToUserName>
                    <FromUserName><![CDATA[%s]]></FromUserName>
                    <CreateTime>%s</CreateTime>
                    <MsgType><![CDATA[text]]></MsgType>
                    <Content><![CDATA[%s]]></Content>
                    </xml>'''
            sr = redis.Redis(connection_pool=REDIS_POOL)

            if len(content_list) == 1:
                if content == '收信':
                    if sr.get(fromUser + 'r'):
                        msg_id = sr.get(fromUser + 'r').decode()
                        msg = Msg.query.filter(Msg.id == msg_id).first()
                        response = make_response(
                            reply % (
                                fromUser, toUser, str(int(time.time())),
                                '您已有一封来信：\n『{}』\n请先回复，格式：回信+内容'.format(msg.msg)))
                    else:
                        msgs = Msg.query.filter(and_(
                            Msg.fromUser != fromUser,
                            Msg.is_delete == 0,
                            not_(Msg.reply_user.contains(fromUser))
                        )).all()
                        if msgs == []:
                            response = make_response(
                                reply % (
                                    fromUser, toUser, str(int(time.time())), '已经没有未回复的信件，请稍后再来。您也可以尝试写信，\n格式：写信+内容'))
                        else:
                            msg = random.choice(msgs)
                            msg.reply_user += (fromUser + '||')
                            sr.set(fromUser + 'r', msg.id)
                            db.session.commit()
                            response = make_response(
                                reply % (
                                fromUser, toUser, str(int(time.time())), '您收到一封来信：\n『{}』\n回信格式：回信+内容'.format(msg.msg)))
                    response.headers['content-type'] = 'application/xml'
                    return response
                elif content == '查看回信':
                    if sr.get(fromUser + 'w'):
                        msg_id = sr.get(fromUser + 'w').decode()
                        msg = Msg.query.filter_by(id=msg_id).first()
                        response = make_response(
                            reply % (fromUser, toUser, str(int(time.time())),
                                     '您收到{}封回信：\n{}'.format(msg.reply_num, msg.reply_list)))
                    else:
                        response = make_response(
                            reply % (fromUser, toUser, str(int(time.time())),
                                     '您还未写信，格式：\n 写信+内容'))
                    response.headers['content-type'] = 'application/xml'
                    return response
                elif content == '结束投递':
                    if sr.get(fromUser + 'w'):
                        msg_id = sr.get(fromUser + 'w').decode()
                        msg = Msg.query.filter_by(id=msg_id).first()
                        msg.is_delete = 1
                        db.session.commit()
                        sr.delete(fromUser + 'w')

                    response = make_response(
                        reply % (fromUser, toUser, str(int(time.time())),
                                 '您现在可以重新写一封信\n格式：写信+内容'))
                    response.headers['content-type'] = 'application/xml'
                    return response
                else:
                    # n_content = bot_reply(content)
                    n_content = '其余功能正在开发...'
                    response = make_response(reply % (fromUser, toUser, str(int(time.time())), n_content))
                    response.headers['content-type'] = 'application/xml'
                    return response
            elif len(content_list) == 2:
                if content_list[0] == '写信':
                    if sr.get(fromUser + 'w'):
                        msg_id = sr.get(fromUser + 'w').decode()
                        msg = Msg.query.filter_by(id=msg_id).first()
                        response = make_response(
                            reply % (fromUser, toUser, str(int(time.time())),
                                     '您已经有一封信正在投递\n『{}』\n如需重新写信请先回复：结束投递\n'.format(msg.msg)))
                    else:
                        msg = Msg()
                        msg.fromUser = fromUser
                        msg.msg = content_list[1]
                        db.session.add(msg)
                        db.session.commit()
                        msg = Msg.query.filter(and_(Msg.fromUser == fromUser, Msg.is_delete == 0)).first()
                        response = make_response(
                            reply % (fromUser, toUser, str(int(time.time())), '您的来信已接收，请等待回信\n如您不想再接受回信\n请回复：结束投递'))
                        sr.set(fromUser + 'w', msg.id)
                    response.headers['content-type'] = 'application/xml'
                    return response
                elif content_list[0] == '回信':
                    msg_id = sr.get(fromUser + 'r')
                    if msg_id:
                        msg = Msg.query.filter_by(id=msg_id.decode()).first()
                        msg.reply_list = msg.reply_list + '\n{}'.format('『%s』' % (str(msg.reply_num) + content_list[1]))
                        msg.reply_num += 1
                        db.session.commit()
                        print('===' + str(msg.reply_num))
                        # if msg.reply_num == 3:
                        #     sr.delete(msg.fromUser + 'w')
                        sr.delete(fromUser + 'r')
                        response = make_response(
                            reply % (fromUser, toUser, str(int(time.time())), '感谢您的回复，您的回信已送达'))
                    else:
                        response = make_response(
                            reply % (fromUser, toUser, str(int(time.time())), '您还没有收信，请回复:\n收信'))
                    response.headers['content-type'] = 'application/xml'
                    return response
                else:
                    return 'success'
            else:
                return 'seccess'
                # return "Hello World"

        # 图片消息
        if msgType == 'image':
            picUrl = xml_data.find('PicUrl').text
            reply = '''<xml>
                      <ToUserName><![CDATA[%s]]></ToUserName>
                      <FromUserName><![CDATA[%s]]></FromUserName>
                      <CreateTime>%s</CreateTime>
                      <MsgType><![CDATA[image]]></MsgType>
                      <Image>
                        <MediaId><![CDATA[%s]]></MediaId>
                      </Image>
                      </xml>'''
            uid = uuid.uuid1()
            cvt(picUrl, uid)
            # time.sleep(1)
            mediaId = get_media_id(uid)

            response = make_response(reply % (fromUser, toUser, str(int(time.time())), mediaId))
            response.headers['content-type'] = 'application/xml'
            return response


if __name__ == '__main__':
    app.run(debug=False, host='0.0.0.0', port=80)
